package com.hopedove.tempdemo.viewmodel

import android.graphics.Bitmap
import android.text.TextUtils
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.bumptech.glide.RequestManager
import com.hadilq.liveevent.LiveEvent
import com.hopedove.net.kotlin.ErrorResult
import com.hopedove.net.kotlin.SuccessResult
import com.hopedove.tempdemo.net.*
import com.hopedove.tempdemo.net.data.*
import com.hopedove.tempdemo.repository.Repository
import com.hopedove.tempdemo.utils.*
import com.hopedove.viewmodel.BaseViewModel
import com.orhanobut.logger.Logger
import kotlinx.coroutines.launch

class ProductionNoticeViewModel(private val api: SoapApi = SoapApi()) : BaseViewModel() {

    private val _productionNotice = MutableLiveData<ProductionNoticeDetail>()
    val productionNoticeDetail: LiveData<ProductionNoticeDetail> = _productionNotice


    private val _triangleArrangeBitmap = MutableLiveData<Bitmap>()
    val triangleArrangeBitmap: LiveData<Bitmap> = _triangleArrangeBitmap

    private val _artDesignBitmap = MutableLiveData<Bitmap>()
    val artDesignBitmap: LiveData<Bitmap> = _artDesignBitmap

    private val _knitArrangeBitmap = MutableLiveData<Bitmap>()
    val knitArrangeBitmap: LiveData<Bitmap> = _knitArrangeBitmap
    private val _knitArrangeContent = MutableLiveData<String>()
    val knitArrangeContent: LiveData<String> = _knitArrangeContent

    private val _response = MutableLiveData<GetProductionNoticeResponse>()
    val response: LiveData<GetProductionNoticeResponse> = _response

    private val _tshtListData = MutableLiveData<List<String>>()
    val tshtListData: LiveData<List<String>> = _tshtListData

    private val _noticeBill = MutableLiveData<NoticeBill>()
    val noticeBill: LiveData<NoticeBill> = _noticeBill

    private val _dsTableData = LiveEvent<List<GridLayoutCell>>()
    val dsTableData: LiveData<List<GridLayoutCell>> = _dsTableData

    fun loadData(glide: RequestManager) = viewModelScope.launch {
        val data = Repository.getSelectedItem() ?: return@launch
        val request = data.let {
            GetProductionNoticeRequest(
                CLOTHGROUP = it.CLOTHGROUP ?: "",
                CONTACTNO = it.CONTACTNO ?: "",
                BH = it.BH ?: "",
                GYSX = it.GYSX ?: "",
                PATTERNNO = it.PATTERNNO ?: "",
            )
        }

        api.getProductionNotice(request).let { result ->
            Logger.d(result)
            when (result) {
                is SuccessResult -> {
                    result.value.let {
                        setBaseInfo(it)
                        setTriangle(it, glide)
                        setArtDesign(it, glide)
                        setKnitDesign(it)
                        setTable(it)
                    }
                }
                is ErrorResult -> {
                    _toastText.value = result.error
                }
            }
        }

        // 获取标签信息
        getLabelBill()
    }


    private fun getLabelBill() = viewModelScope.launch {
        val data = Repository.getSelectedItem() ?: return@launch
        api.getNoticeBillInfo(data.SCLOTHTKTNO ?: "").let { result ->
            when (result) {
                is SuccessResult -> {
                    if (result.value.isNotEmpty()) {
                        _noticeBill.value = result.value[0]
                    }

                }
                is ErrorResult -> {

                }
            }
        }
    }

    private fun setBaseInfo(resp: GetProductionNoticeResponse) {
        _response.value = resp
        resp.rst?.let { _productionNotice.value = it }
    }

    // 三角排列
    private fun setTriangle(resp: GetProductionNoticeResponse, glide: RequestManager) =
        viewModelScope.launch {
            resp.rst_sjpl?.let { info ->
                Repository.buildTriangleArrange(
                    viewModelScope,
                    glide,
                    info.YNUM!!,
                    info.XNUM!!,
                    resp.sjpl!!
                )?.let {
                    _triangleArrangeBitmap.value = it
                }
            }
        }

    // 意匠图
    private fun setArtDesign(resp: GetProductionNoticeResponse, glide: RequestManager) =
        viewModelScope.launch {
            resp.yjt?.let {
                buildArtDesign(it, glide)?.let { bitmap ->
                    _artDesignBitmap.value = bitmap
                }
            }
        }

    private suspend fun buildArtDesign(
        list: List<ArtDesignItem>,
        glide: RequestManager
    ): Bitmap? {
        val cols = 1 + (list.distinctBy { it.XCELL }.map { it.XCELL }.maxOrNull() ?: return null)
        val rows = 1 + (list.distinctBy { it.YCELL }.map { it.YCELL }.maxOrNull() ?: return null)
        Logger.d("rows: $rows, cols: $cols")

        val builder = GridBitmapBuilder(
            rows,
            cols,
            sideIndicate = setOf(SideIndicate.Bottom(), SideIndicate.Left(false))
        )

        val bitmap = builder.build()

        // 收集所有的 url 对应的 bitmap
        val urls = list.map { it.VAL }.distinct()
        val map = collectMappingBitmaps(viewModelScope, glide, urls)

        val images = mutableListOf<GridCellBitmap>()
        for (item in list) {
            map[item.VAL]?.let { bmp ->
                images.add(GridCellBitmap(bmp, item.YCELL, item.XCELL))
            }
        }
        builder.drawCellBitmaps(images, GridCellCoordinate.LeftTop)

        return bitmap
    }

    // 织针排列
    private fun setKnitDesign(resp: GetProductionNoticeResponse) {

        resp.rst_zzpl?.let { zzpl ->
            zzpl.tables?.let { tables ->
                val above = tables.above.info.let { TableSize(it.rows, it.columns) }
                val below = tables.below?.info?.let { TableSize(it.rows, it.columns) }
                val aboveLeftMargin = if (tables.above.info.hasLeftMargin) 40 else 0
                val belowLeftMargin = if (tables.below?.info?.hasLeftMargin == true) 40 else 0

                val helper = KnitArrangementHelper(
                    above,
                    below,
                    aboveLeftMargin,
                    belowLeftMargin,
                    tables.hasDivider
                )

                val datas = mutableListOf<KnitArrangeCell>()
                datas.addAll(tables.above.data.map { KnitArrangeCell(it.y, it.x, it.`val`) })
                datas.addAll(tables.below?.data?.map {
                    KnitArrangeCell(
                        it.y,
                        it.x,
                        it.`val`,
                        false
                    )
                } ?: mutableListOf())

                _knitArrangeBitmap.value = helper.drawCells(datas)
            }
        }

        resp.rst_zzpl?.imgData?.let { imageData ->
            if (!TextUtils.isEmpty(imageData)) {
                _knitArrangeBitmap.value = BitmapUtil.fromBase64(imageData)
                resp.rst_zzpl?.remark?.let {
                    _knitArrangeContent.value = it
                }
            }
        }

        resp.rst_zzpl?.tspl?.let { content ->
            _knitArrangeContent.value = content.replace("\r", "")
        }
    }


    // ds 表格
    private fun setTable(resp: GetProductionNoticeResponse) {
        jsonElementParseTo(resp.ds).let {
            if (it.isNotEmpty()) {
                Logger.d("${it[0].dimensionSize}")
                _dsTableData.value = it
            }
        }
    }


}